iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 24
0
自我挑戰組

JS 作品實戰應用 - Vue 電商網站系列 第 24

24. Vue 常用指令與方法 4

  • 分享至 

  • xImage
  •  

v-if, v-else, v-else-if

v-if 用於條件的方式渲染一個區塊,當指令的內容回傳為真值時會產生結構內容。

// html
<div id="app">
  <h4>v-if, v-else</h4>
  <div class="alert alert-success" v-if="isSuccess">成功!</div>
  <div class="alert alert-danger" v-else>失敗!</div>
  <div class="form-check">
    <input type="checkbox" class="form-check-input" id="isSuccess" v-model="isSuccess">
    <label class="form-check-label" for="isSuccess">啟用元素狀態</label>
  </div>

  <h4>v-else-if</h4>
  <ul class="nav nav-tabs">
    <li class="nav-item">
      <a class="nav-link" href="#" :class="{'active': link === 'a'}" @click="link = 'a'">標題一</a>
    </li>
    <li class="nav-item">
      <a class="nav-link" href="#" :class="{'active': link === 'b'}" @click="link = 'b'">標題二</a>
    </li>
    <li class="nav-item">
      <a class="nav-link" href="#" :class="{'active': link === 'c'}" @click="link = 'c'">標題三</a>
    </li>
  </ul>
  <div class="content">
    <div v-if="link === 'a'">A</div>
    <div v-else-if="link === 'b'">B</div>
    <div v-else-if="link === 'c'">C</div>
  </div>
</div>

// JS
var app = new Vue({
  el: '#app',
  data: {
    isSuccess: true,
    link: 'a',
  },
});
  • 當 v-if 的結果為真值時,則會置入該區塊的結構內容
  • v-else, v-else-if 則為 v-if 的延伸運用,會延續著 v-if 的結構後方
    課程範例

v-show

v-showv-if 同樣是用來切換物件的呈現,但兩者有差異:

  • v-if 會完整移除 DOM 元素,使其從 HTML 結構上消失。當使用此方法切換 Vue 元件時,元件的生命週期會重新計算。
  • v-show 是將物件加上 display: none,讓物件從視覺上不可見。

此方法運行結果與上述相同,但元素是套用 display: none 作為顯示上的切換。

v-ifv-show 怎麼選擇?

  • 當元件生命週期需要在顯示時重新計算,則可以使用 v-if,如果則否可用 v-show
  • 當元件隱藏時,同時需要完整移除 DOM 結構,也可使用 v-if
  • v-if 與 v-for 則有另外的衝突問題,會在 v-for 章節詳細說明。
// html
<div id="app">
  <div class="alert alert-success" v-show="isSuccess">成功!</div>
  <div class="alert alert-danger" v-show="!isSuccess">失敗!</div>
  <div class="form-check">
    <input type="checkbox" class="form-check-input" id="isSuccess" v-model="isSuccess">
    <label class="form-check-label" for="isSuccess">啟用元素狀態</label>
  </div>
</div>

// JS
var app = new Vue({
  el: '#app',
  data: {
    isSuccess: true,
  },
});

請使用開發者工具檢視畫面上的「成功、失敗」區塊,可以發現是使用 display: none 的方式隱藏,而不是移除整個 DOM 結構。
課程範例

v-for

v-for 可以針對一組陣列或物件進行渲染,指令中會使用 (item, key) in array 的語法,其中:

  • item:陣列迭代的元素別名,名稱可自訂
  • key:如果是陣列則為該迭代的索引位置,如果是物件則為該迭代的物件屬性
  • array:陣列或資料的來源

範例為陣列、物件搭配迴圈的方式:

// html
<div id="app">
  <h4>陣列與物件的迴圈</h4>
  <ul>
    <li v-for="(item, key) in arrayData">
      {{ key }} - {{ item.name }} {{ item.age }} 歲
    </li>

    <li v-for="(item, key) in objectData">
      {{ key }} - {{ item.name }} {{ item.age }} 歲
    </li>
  </ul>
</div>

// JS
var app = new Vue({
  el: '#app',
  data: {
    arrayData: [
      {
        name: 'Gary',
        age: 35
      },
      {
        name: 'Tony',
        age: 28
      },
      {
        name: 'Jack',
        age: 33
      }
    ],
    objectData: {
      casper: {
        name: 'Gary',
        age: 35
      },
      ray: {
        name: 'Tony',
        age: 32
      },
      gonsakon: {
        name: 'Jack',
        age: 33
      }
    },
  }
});
  • v-for 的結構為 v-for="(item, key) in array"
  • 無論是陣列、物件都可以使用 v-for
  • 陣列的索引為 0, 1, 2...,物件索引則為屬性名稱
    課程範例

v-for 注意事項

由於 v-for 在運作上是採用快速替換的形式。因此,有部分元素會沒有完整的被替換,可參考以下範例:

情境,當 input 輸入內容後,按下反轉陣列時:

  • 如果沒有 key 時,則 input 位置不會被同時更動
  • 當有加上 key 時,input 位置會與原本的資料內容位置一起變動

新版的 Vue 相關開發工具中,都會強烈建議加上 key

// html
<div id="app">
  <h4>缺少 key</h4>
  <ul>
    <li v-for="(item, key) in arrayData" >
      {{ key }} - {{ item.name }} {{ item.age }} 歲 <input type="text">
    </li>
  </ul>

  <h4>加上 key</h4>
  <ul>
    <li v-for="(item, key) in arrayData" :key="item.age">
      {{ key }} - {{ item.name }} {{ item.age }} 歲 <input type="text">
    </li>
  </ul>
  <button class="btn btn-outline-primary" @click="reverseArray">反轉陣列</button>
</div>

// JS
var app = new Vue({
  el: '#app',
  data: {
    arrayData: [
      {
        name: 'Gary',
        age: 35
      },
      {
        name: 'Tony',
        age: 28
      },
      {
        name: 'Jack',
        age: 33
      }
    ]
  },
  methods: {
    reverseArray: function () {
      this.arrayData.reverse()
      console.log(this.arrayData)
    },
  }
});
  • 範例最下方有一個反轉陣列的按鈕,按下後會反轉上方的結構
  • 試著輸入一些內容,並反轉整個結構
  • 注意元素中是否有 key 屬性,這會影響到是否能夠 input 是否有隨著結構反轉
    課程範例

Template

當渲染陣列資料卻不便產生新的標籤時,可以搭配 <template> 標籤做使用,此方法即可在產生 DOM 結構時不產生額外的標籤。另外 template 標籤也同樣可用於 v-for

// html
<div id="app">
  <h4>Template 的運用</h4>
  <table class="table">
    <tbody>
      <template v-for="(item, key) in arrayData">
        <tr>
          <td>{{ key }}</td>
          <td>{{ item.name }}</td>
          <td>{{ item.age }} 歲</td>
        </tr>
      </template>
    </tbody>
  </table>
</div>

// JS
var app = new Vue({
  el: '#app',
  data: {
    arrayData: [
      {
        name: 'Gary',
        age: 35
      },
      {
        name: 'Tony',
        age: 28
      },
      {
        name: 'Jack',
        age: 33
      }
    ]
  },
  methods: {
    reverseArray: function () {
      this.arrayData.reverse()
      console.log(this.arrayData)
    },
  }
});

可以使用 template 標籤替代原有的 HTML 標籤,而 template 標籤是不會被輸出的。
課程範例

避免 v-if 和 v-for 用在一起

為了避免不要的錯誤,Vue.js 的規範中建議不要將 v-for 與 v-if 混合使用。搭配進階工具如 Vue Cli 及 ESLint 時,兩者混合使用會跳出錯誤。

// html
<div id="app">
  <table class="table">
    <tbody>
      <template v-for="(item, key) in arrayData">
        <tr v-if="item.age > 30">
          <td>{{ key }}</td>
          <td>{{ item.name }}</td>
          <td>{{ item.age }} 歲</td>
        </tr>
      </template>
    </tbody>
  </table>
</div>

// JS
var app = new Vue({
  el: '#app',
  data: {
    arrayData: [
      {
        name: 'Gary',
        age: 35
      },
      {
        name: 'Tony',
        age: 28
      },
      {
        name: 'Jack',
        age: 33
      }
    ],
  },
});

盡可能將 v-if 與 v-for 用不同的標籤呈現
課程範例


上一篇
23. Vue 常用指令與方法 3
下一篇
25. Vue指令練習
系列文
JS 作品實戰應用 - Vue 電商網站30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言